Конфигурация модуля (config.yaml)
Как это работает
Keeper монтирует файл config.yaml в контейнер и устанавливает переменную окружения CONFIG_FILE с путём к нему. SDK читает YAML и маппит его на Pydantic-модель.
Все параметры (и системные, и ваши кастомные) живут внутри блока additional в YAML-файле.
Шаг 1. Создайте config.py
Расширьте класс Additional, добавив поля вашего модуля:
# config.py
from typing import Optional
from module_sdk.config.config_model import Additional, BaseConfig, getConfigPath
class ConnectorAdditional(Additional):
"""Ваши поля — добавляются к стандартным port, max_chunk_size, run_place_type."""
# URL внешнего API (обязательное)
api_url: str
# Токен авторизации (подставляется из Vault через [[KEY]])
api_token: str
# Опциональные поля с дефолтами
page_size: Optional[int] = 100
timeout: Optional[int] = 30
responsible_id: Optional[str] = "00000000-0000-0000-0000-000000000000"
class ConnectorConfig(BaseConfig):
additional: ConnectorAdditional
# Загрузка конфига — выполняется один раз при импорте модуля
config: ConnectorConfig = ConnectorConfig.read_yaml(getConfigPath(), ConnectorConfig)
Класс Additional из SDK уже содержит три системных поля:
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
port | int | обязательное | Порт HTTP-сервера модуля |
max_chunk_size | int | 500 | Максимум ассетов в одном пакете |
run_place_type | str | "empty" | Тип запуска |
Ваши поля добавляются к ним в наследнике ConnectorAdditional.
Шаг 2. Создайте config.yaml
Все поля (системные + ваши) — внутри блока additional:
# config.yaml
additional:
# --- Системные поля SDK ---
port: 8383
max_chunk_size: 500
# --- Ваши поля (должны совпадать с ConnectorAdditional) ---
api_url: "https://external-system.example.com/api/v1"
api_token: "[[API_TOKEN]]" # Секрет из Vault
page_size: 100
timeout: 30
responsible_id: "00000000-0000-0000-0000-000000000000"
!!! warning
Все кастомные поля должны быть внутри additional:. Поля на корневом уровне YAML будут проигнорированы.
Шаг 3. Используйте конфиг в main.py
# main.py
from module_sdk.app.app import AppModule
from module_sdk.storage.storage import scan_status_storage
from config import config # <-- импорт вашего конфига
import logging
log = logging.getLogger(__name__)
def collect_data():
log.info("Подключаемся к %s", config.additional.api_url)
# Все поля доступны через config.additional.*
api_url = config.additional.api_url
token = config.additional.api_token
page_size = config.additional.page_size
timeout = config.additional.timeout
responsible = config.additional.responsible_id
# ... ваша логика сбора данных ...
if __name__ == "__main__":
AppModule.app_create_and_do_py(collect_data)
Секреты (Vault)
Секреты хранятся в HashiCorp Vault и подставляются Keeper'ом перед запуском модуля. В конфиге используется синтаксис [[KEY]]:
additional:
api_token: "[[MY_SECRET_TOKEN]]"
db_password: "[[DB_PASSWORD]]"
Keeper заменяет [[MY_SECRET_TOKEN]] на реальное значение из Vault перед монтированием конфига в контейнер. В коде вы получаете уже готовое значение:
token = config.additional.api_token # уже "реальный-токен-из-vault"
Частые ошибки конфигурации
| Ошибка | Причина | Решение |
|---|---|---|
ValidationError: field required | Обязательное поле не указано в YAML | Добавьте поле в additional: блок YAML |
Поле None хотя в YAML значение есть | Поле написано на корневом уровне, не внутри additional: | Переместите поле внутрь additional: |
EnvironmentError: Not found ENV -> CONFIG_FILE | Не задана переменная окружения | CONFIG_FILE=./config.yaml python3 main.py |